﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using PictureManager.Core;
using System.Data;
using System.Drawing;
using System.Threading;
using System.IO;
using System.Windows.Media.Animation;
using Infrastructure.UI.WPF;

namespace PictureManager.WPF
{
    /// <summary>
    /// Interaction logic for frmMaintenance.xaml
    /// </summary>
    public partial class frmMaintenance : BaseForm
    {
        #region Fields
        private String RootNode;
        private PictureItem currentItem;
        private TreeViewItem draggedItem;
        private TreeViewItem target;
        private List<PictureRow> PictureList = new List<PictureRow>();
        private class PictureRow
        {
            internal String FileName { get; set; }
            internal String Path { get; set; }
            internal BitmapImage Image { get; set; }
        }
        private System.Threading.Timer asyncTimer;
        #endregion


        public frmMaintenance()
        {
            InitializeComponent();
        }

        public override void InitData()
        {
            base.InitData();
            RootNode = PictureSettings.Instance.PictureRootNode;
            BindingTreeView(RootNode, treeViewPicture.Items);

        }

        public override void InitEvent()
        {
            base.InitEvent();
            try
            {
                this.treeViewPicture.DragOver += new DragEventHandler(treeViewPicture_DragOver);
                this.treeViewPicture.Drop += new DragEventHandler(treeViewPicture_Drop);
                this.treeViewPicture.SelectedItemChanged += new RoutedPropertyChangedEventHandler<object>(treeViewPicture_SelectedItemChanged);
                asyncTimer = new System.Threading.Timer(delegate
                    {
                        this.Dispatcher.Invoke((Action)delegate
                        {
                            if (this.progressBar1.Value == this.progressBar1.Maximum)
                                this.progressBar1.Value = 0;
                            else
                                this.progressBar1.Value += 1;
                        }, null);
                    }, null, -1, 1000);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        void treeViewPicture_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            SaveCurrentItem();
            if (e.NewValue == null) return;
            TreeViewItem newItem = e.NewValue as TreeViewItem;
            if (newItem != null)
            {
                PictureItem item = newItem.Tag as PictureItem;
                currentItem = item;
                BindingControl();
            }
        }

        void treeViewPicture_Drop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                #region FileDrop
                string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
                if (files.All(f => !System.IO.Directory.Exists(f))) return;
                BackgroundWorker(true);
                Func<String[], bool> syncAllOper = new Func<string[], bool>(LoadAllDirectory);
                syncAllOper.BeginInvoke(files,
                    new AsyncCallback(delegate(IAsyncResult ar)
                    {
                        this.Dispatcher.Invoke(
                        (Action)delegate
                        {
                            if (!syncAllOper.EndInvoke(ar))
                            {
                                MessageBox.Show(PictureManager.WPF.Properties.Resources.FailtoLoadAll, PictureManager.WPF.Properties.Resources.Error, MessageBoxButton.OK, MessageBoxImage.Error);
                            }
                            else
                            {
                                PictureItem.SaveAll();
                                MessageBox.Show(PictureManager.WPF.Properties.Resources.LoadAllSuccessfully, PictureManager.WPF.Properties.Resources.Information, MessageBoxButton.OK, MessageBoxImage.Information);
                            }
                            RefreshTreeView();
                            BackgroundWorker(false);
                        }
                    );
                    }), null);
                #endregion
            }
            else if (e.OriginalSource is UIElement)
            {
                target = GetNearestContainer<TreeViewItem>(e.OriginalSource as UIElement);
                if (draggedItem == null) return;
                PictureItem dragItem = draggedItem.Tag as PictureItem;
                if (target == null && dragItem != null && dragItem.ParentID != PictureSettings.Instance.PictureRootNode)
                {
                    dragItem.ParentID = PictureSettings.Instance.PictureRootNode;
                }
                else
                {
                    PictureItem desItem = target.Tag as PictureItem;
                    if (desItem == null || dragItem == null || dragItem.ParentID == desItem.ID)
                        return;
                    dragItem.ParentID = desItem.ID;
                }

                dragItem.SetRelativePathEmpty();
                PictureItem.SaveAll();
                RefreshTreeView();
                target = null;
                draggedItem = null;
            }
        }

        void treeViewPicture_DragOver(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop) || e.Data.GetDataPresent("System.Windows.Forms.TreeNode", false))
            {
                e.Effects = DragDropEffects.Move;
            }
        }

        private void BindingControl()
        {
            BindingControl(currentItem);
        }

        private void BindingControl(PictureItem currentItem)
        {
            this.grpDetail.DataContext = currentItem;
            grpPicture.Children.Clear();
            (from t in currentItem.FileNames
             select new
             {
                 FileName = t.Value,
                 Path = t.Key
             }).ToList().ForEach(k =>
                  {
                      try
                      {
                          System.Windows.Controls.Image image = new System.Windows.Controls.Image();
                          System.Drawing.Image img = System.IO.File.Exists(k.Path) ? System.Drawing.Image.FromFile(k.Path) : new Bitmap(100, 100);
                          System.Drawing.Image bmp = new System.Drawing.Bitmap(img);
                          img.Dispose();

                          System.Drawing.Image bitmapImage = GraphicsImage(bmp);
                          image.Source = new BitmapImage(new Uri(k.Path));
                          image.ToolTip = k.FileName;
                          if (bitmapImage != null)
                          {
                              image.Height = bitmapImage.Height;
                              image.Width = bitmapImage.Width;
                              
                              //DoubleAnimation daWidth = new DoubleAnimation(image.Width, image.Width * 5, new Duration(TimeSpan.FromSeconds(0.5)));
                              //DoubleAnimation daHeight = new DoubleAnimation(image.Height, image.Height * 5, new Duration(TimeSpan.FromSeconds(0.5)));
                              //Storyboard sbImage = new Storyboard();
                              //sbImage.Children.Add(daWidth);
                              //sbImage.Children.Add(daHeight);
                              //Storyboard.SetTarget(daWidth, image);
                              //Storyboard.SetTarget(daHeight, image);
                              //Storyboard.SetTargetProperty(daWidth, new PropertyPath("Width"));
                              //Storyboard.SetTargetProperty(daHeight, new PropertyPath("Height"));
                              //EventTrigger et = new EventTrigger(System.Windows.Controls.Image.MouseEnterEvent);
                              //BeginStoryboard bsb = new BeginStoryboard();
                              //bsb.Storyboard = sbImage;
                              //et.Actions.Add(bsb);
                              //image.Triggers.Add(et);

                              //DoubleAnimation daWidth2 = new DoubleAnimation(200, image.Width, new Duration(TimeSpan.FromSeconds(0)));
                              //DoubleAnimation daHeight2 = new DoubleAnimation(200, image.Height, new Duration(TimeSpan.FromSeconds(0)));
                              //Storyboard sbImage2 = new Storyboard();
                              //sbImage2.Children.Add(daWidth2);
                              //sbImage2.Children.Add(daHeight2);
                              //Storyboard.SetTarget(daWidth2, image);
                              //Storyboard.SetTarget(daHeight2, image);
                              //Storyboard.SetTargetProperty(daWidth2, new PropertyPath("Width"));
                              //Storyboard.SetTargetProperty(daHeight2, new PropertyPath("Height"));
                              //EventTrigger et2 = new EventTrigger(System.Windows.Controls.Image.MouseLeaveEvent);
                              //BeginStoryboard bsb2 = new BeginStoryboard();
                              //bsb2.Storyboard = sbImage2;
                              //et2.Actions.Add(bsb2);
                              //image.Triggers.Add(et2);
                              grpPicture.Children.Add(image);
                          }
                      }
                      catch (Exception ex)
                      {
                          System.Diagnostics.Debug.Write(ex.Message);
                      }
                  });
        }


        private BitmapImage GetBitmapImage(string Path)
        {
            BitmapImage bitmapImage = System.IO.File.Exists(Path) ? new BitmapImage(new Uri(Path)) : new BitmapImage();
            return GraphicsImage(bitmapImage);
        }
        private BitmapImage GraphicsImage(BitmapSource image)
        {
            while (image.Height > 200 || image.Width > 200)
                image = new TransformedBitmap(image, new ScaleTransform(0.5, 0.5));
            return image as BitmapImage;
        }
        private System.Drawing.Image GraphicsImage(System.Drawing.Image image)
        {
            while (image.Height > 100 && image.Width > 100)
                image = GraphicsControl.Instance.ReSizeImage(image, new System.Drawing.Size(image.Width / 2 == 0 ? image.Width : image.Width / 2, image.Height / 2 == 0 ? image.Height : image.Height / 2));
            return image;
        }
        private void EndCurrentEdit()
        {
            if (currentItem != null)
            {
                currentItem.SetRelativePathEmpty();
            }
        }

        private void SaveCurrentItem()
        {
            if (currentItem != null)
            {
                EndCurrentEdit();
                currentItem.Save();
            }
        }

        private void BindingTreeView(string parentID, ItemCollection nodeCollection)
        {
            PictureItem.PictureList.Where(p => p.ParentID == parentID).ToList().ForEach(p =>
            {
                TreeViewItem node = new TreeViewItem();
                node.Header = p.Name;
                node.Tag = p;
                node.PreviewMouseMove += new MouseEventHandler(node_PreviewMouseMove);
                nodeCollection.Add(node);
                BindingTreeView(p.ID, node.Items);

            });
        }

        void node_PreviewMouseMove(object sender, MouseEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                System.Windows.Point currentPosition = e.GetPosition(this.treeViewPicture);
                draggedItem = (TreeViewItem)treeViewPicture.SelectedItem;
            }
        }

        private void RefreshTreeView()
        {
            treeViewPicture.Items.Clear();
            BindingTreeView(RootNode, treeViewPicture.Items);
            BindingControl();
        }
        private bool LoadAllDirectory(String[] Paths)
        {
            bool isLoadSuccessful = true;
            for (int i = 0; i <= Paths.Length - 1; i++)
            {
                if (!System.IO.Directory.Exists(Paths[i])) continue;
                isLoadSuccessful = isLoadSuccessful && PictureManager.Core.Util.LoadDirectory(Paths[i], PictureSettings.Instance.PictureRootNode);
            }
            return isLoadSuccessful;
        }

        private void BackgroundWorker(Boolean isBackgroundWork)
        {
            if (isBackgroundWork)
            {
                this.progressBar1.Visibility = Visibility.Visible;
                asyncTimer.Change(0, 1000);
            }
            else
            {
                this.progressBar1.Visibility = Visibility.Hidden;
                asyncTimer.Change(-1, -1);
            }
        }

        private T GetNearestContainer<T>(UIElement element) where T : UIElement
        {
            // Walk up the element tree to the nearest tree view item.
            T container = element as T;
            while ((container == null) && (element != null))
            {
                element = VisualTreeHelper.GetParent(element) as UIElement;
                container = element as T;
            }
            return container;
        }

        private void chkShowPathColumn_Checked(object sender, RoutedEventArgs e)
        {
            // this.colPath.Visibility = Visibility.Visible;
        }

        private void chkShowPathColumn_Unchecked(object sender, RoutedEventArgs e)
        {
            // this.colPath.Visibility = Visibility.Hidden;
        }
    }
}
